// #include <iostream>
// #include <mutex>
// #include <atomic>
// #include <muduo/net/TcpClient.h>
// #include <muduo/net/EventLoop.h>
// #include <muduo/net/EventLoopThread.h>
// #include <muduo/net/TcpConnection.h>
// #include <muduo/net/Buffer.h>
// #include <muduo/base/CountDownLatch.h>

// class DictClient
// {
// public:
//     DictClient(const std::string& sip, int sport):
//     _loopthread(),
//     _baseloop(_loopthread.startLoop()),
//     _client(_baseloop, muduo::net::InetAddress(sip, sport), "DictClient"),
//     _downlatch(1),
//     _disconnecting(false)
//     {
//         _client.setConnectionCallback(
//             std::bind(&DictClient::onConnection, this, std::placeholders::_1));
        
//         _client.setMessageCallback(
//             std::bind(&DictClient::onMessage, this, std::placeholders::_1,
//                       std::placeholders::_2, std::placeholders::_3));

//         _client.enableRetry();
//         _client.connect();
//         _downlatch.wait();
//     }
    
//     ~DictClient()
//     {
//         disconnect();
//         // 确保所有回调都已完成
//         if (_baseloop) {
//             _baseloop->assertInLoopThread();
//         }
//     }
    
//     bool send(const std::string& msg)
//     {
//         muduo::net::TcpConnectionPtr conn;
//         {
//             std::lock_guard<std::mutex> lock(_mutex);
//             if (_disconnecting || !_conn || !_conn->connected())
//             {
//                 std::cout << "连接已断开，发送数据失败！\n";
//                 return false;
//             }
//             conn = _conn; // 创建副本，保持引用计数
//         }
        
//         // 在临界区外调用send，避免长时间持有锁
//         conn->send(msg);
//         return true;
//     }

// private:
//     void onConnection(const muduo::net::TcpConnectionPtr& conn)
//     {
//         std::lock_guard<std::mutex> lock(_mutex);
        
//         if (!_disconnecting) {
//             if (conn->connected())
//             {
//                 std::cout << "建立连接!\n";
//                 if (_downlatch.getCount() > 0)
//                     _downlatch.countDown();
//                 _conn = conn;
//             }
//             else
//             {
//                 std::cout << "连接断开\n";
//                 _conn.reset();
//             }
//         }
//     }
    
//     void onMessage(const muduo::net::TcpConnectionPtr& conn, 
//                   muduo::net::Buffer* buf, 
//                   muduo::Timestamp)
//     {
//         std::string res = buf->retrieveAllAsString();
//         std::cout << res << std::endl;
//     }
    
//     void disconnect()
//     {
//         {
//             std::lock_guard<std::mutex> lock(_mutex);
//             _disconnecting = true;
//             if (_conn)
//             {
//                 _conn->shutdown();
//                 _conn.reset();
//             }
//         }
        
//         // 必须在EventLoop线程中调用disconnect
//         if (_baseloop) {
//             _baseloop->runInLoop(
//                 std::bind(&muduo::net::TcpClient::disconnect, &_client));
//         }
//     }

// private:
//     std::mutex _mutex;
//     std::atomic<bool> _disconnecting;
//     muduo::net::TcpConnectionPtr _conn;
//     muduo::CountDownLatch _downlatch;
//     muduo::net::EventLoopThread _loopthread;
//     muduo::net::EventLoop* _baseloop;
//     muduo::net::TcpClient _client;
// };


// int main()
// {
//     DictClient client("127.0.0.1", 9090);

//     while(true)
//     {
//         std::string msg;
//         std::getline(std::cin, msg); // 使用getline可以读取包含空格的消息
//         if (msg == "quit")
//             break;
//         client.send(msg);
//     }
    
//     return 0;
// }


#include<iostream>
#include<string>
#include<muduo/net/TcpClient.h>
#include<muduo/net/TcpConnection.h>
#include<muduo/net/Buffer.h>
#include<muduo/net/EventLoop.h>
#include<muduo/base/CountDownLatch.h>
#include<muduo/net/EventLoopThread.h>

class DictClient
{
public:
    DictClient(const std::string& sip, int sport):_downlatch(1),//计数初始为1，为0时唤醒阻塞
    _baseloop(_loopthread.startLoop()),
    _client(_baseloop, muduo::net::InetAddress(sip, sport), "DictClient")
    {
        _client.setConnectionCallback(std::bind(&DictClient::onConnection, this, std::placeholders::_1));
        _client.setMessageCallback(std::bind(&DictClient::onMessage, this, 
            std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));

        //连接服务器
        _client.connect();
        _downlatch.wait();
    }
    bool send(const std::string& msg)
    {
        if(!_conn->connected())
        {
            std::cout<<"连接失败\n";
            return false;
        }
        _conn->send(msg);
        return true;
    }
private:
    void onConnection(const muduo::net::TcpConnectionPtr& conn)
    {
        if(conn->connected())
        {
            std::cout<<"建立连接\n";
            _downlatch.countDown(); //计数--，为0时唤醒阻塞
	    _conn = conn;
        }
        else
        {
            std::cout<<"连接断开\n";
            _conn.reset();
        }
    }
    void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer *buff, muduo::Timestamp)
    {
        std::string ret = buff->retrieveAllAsString();
        std::cout<< ret <<std::endl;
    }
private:
    muduo::net::TcpConnectionPtr _conn;
    muduo::CountDownLatch _downlatch;
    muduo::net::EventLoopThread _loopthread;
    muduo::net::EventLoop* _baseloop;
    muduo::net::TcpClient _client;
};

int main()
{
    DictClient client("127.0.0.1", 9090);
    while(1)
    {
        std::string msg;
        client.send(msg);
    }
    return 0;
}
